package com.example.musicplayer.service;

import java.io.IOException;

import com.example.musicplayer.MusicPlayActivity;
import com.example.musicplayer.R;
import com.example.musicplayer.bean.Music;
import com.example.musicplayer.common.MusicConstant;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteException;
import android.util.Log;

public class MusicService extends Service implements OnPreparedListener, OnErrorListener {
    private static final String LOG_TAG = MusicService.class.getSimpleName();

    public static final String ACTION_PLAY = "action.play";
    public static final String ACTION_PAUSE = "action.pause";
    public static final String ACTION_STOP = "action.stop";
    public static final String ACTION_QUIT = "action.quit";

    private MediaPlayer mMediaPlayer;

    private String mCurrentSongName;
    private Uri mCurrentMusicUri;
    private String mCurrentMusicPath;

    private boolean mStoped = false;

    private int NOTIFICATION_ID = 1;

    public MusicService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mStub;
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (ACTION_PLAY.equals(intent.getAction())) {
            mCurrentMusicUri = intent.getData();

            initMediaPlayer();

            mCurrentSongName = intent.getStringExtra(MusicConstant.EXTRA_SONG_NAME);
            mCurrentMusicPath = intent.getStringExtra(MusicConstant.EXTRA_SONG_PATH);

            initNotification();
        } else if (ACTION_PAUSE.equals(intent.getAction())) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.stop();
            }
        } else if (ACTION_STOP.equals(intent.getAction())) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.reset();
            }
        } else if (ACTION_QUIT.equals(intent.getAction())) {
            stopSelf();
        }
        return START_NOT_STICKY;
    }

    private void initMediaPlayer() {
        if (mMediaPlayer == null) {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnErrorListener(this);
            mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
        } else if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.reset();
        } else {
            mMediaPlayer.reset();
        }
        if (mCurrentMusicUri != null) {
            setMusicUri(mCurrentMusicUri);
        } else if (mCurrentMusicPath != null) {
            setMusicPath(mCurrentMusicPath);
        }
        mMediaPlayer.prepareAsync(); // prepare async to not block main thread
    }

    private void setMusicUri(Uri uri) {
        try {
            mMediaPlayer.setDataSource(getApplicationContext(), uri);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void setMusicPath(String path) {
        try {
            mMediaPlayer.setDataSource(path);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initNotification() {
        Intent intent = new Intent(getApplicationContext(), MusicPlayActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
                0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder builder = new Notification.Builder(getApplicationContext());
        builder.setSmallIcon(R.drawable.ic_launcher);
        builder.setOngoing(true);
        builder.setContentTitle(mCurrentSongName);
        builder.setContentText("Playing " + mCurrentSongName);

        Notification notification = builder.getNotification();

        // Make this service run in the foreground
        startForeground(NOTIFICATION_ID, notification);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.d(LOG_TAG, "onPrepared called.");
        if (!mStoped) {
            mp.start();
            mStoped = false;
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private IMusicService.Stub mStub = new IMusicService.Stub() {

        @Override
        public void stop() throws RemoteException {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mStoped = true;
                mMediaPlayer.prepareAsync();
            }
        }

        @Override
        public void seek(long position) throws RemoteException {
            if (mMediaPlayer != null) {
                mMediaPlayer.seekTo((int) position);
            }
        }

        @Override
        public void prev() throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public long position() throws RemoteException {
            if (mMediaPlayer != null) {
                return mMediaPlayer.getCurrentPosition();
            }
            return 0L;
        }

        @Override
        public void playList(long[] ids, int position) throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public void play() throws RemoteException {
            if (mMediaPlayer != null) {
                mMediaPlayer.start();
                mStoped = false;
            }
        }

        @Override
        public void pause() throws RemoteException {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
            }
        }

        @Override
        public void open(String path) throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public void next() throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public boolean isPlaying() throws RemoteException {
            return mMediaPlayer != null && mMediaPlayer.isPlaying();
        }

        @Override
        public long[] getPlayingList() throws RemoteException {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long duration() throws RemoteException {
            if (mMediaPlayer != null) {
                return mMediaPlayer.getDuration();
            }
            return 0L;
        }

        @Override
        public void setCallback(IMusicServiceCallback cb) throws RemoteException {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void setLogging(int level) throws RemoteException {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void playMusic(Music music) throws RemoteException {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void playMusics(Music[] musics) throws RemoteException {
            // TODO Auto-generated method stub
            
        }
    };
}